package com.mod.enemies 
{
	import com.calefk.core.List;
	import com.calefk.core.Task;
	import com.calefk.modules.math.Vector2D;
	import com.calefk.util.Generic;
	import com.calefk.util.helper;
	import com.calefk.util.Iterator;
	import com.mod.data.dtEnemy;
	import com.mod.data.dtLevel;
	import com.mod.Global;
	import com.mod.reanimator.HeartSkin;
	import flash.display.MovieClip;
	/**
	 * ...
	 * @author ...
	 */
	public class EnemyManager {
		
		private var mList:List = new List();
		private var mTasks:List;
		private var mCanvas:MovieClip;
		
		private var mColumns:int;
		private var mRows:int;
		
		public function get columns():int { return mColumns; }
		public function get rows()   :int { return mRows;    }
		public function get list()   :List { return mList;    }
		
		/**
		 * Variable que sirve para hacer el pathfinding
		 */
		private var mMapBits:Array;
		private var mBaseBorders:Array;
		
		private var mTilesTest:Array = new Array();
		
		public function get mapbits():Array { return Global.mapBits; }
		public function get baseborders():Array { return mBaseBorders; }
		
		private var mCountEnenmies:int = 0;
		private var mDataLevel:dtLevel;
		private var mDataEnemies:Array;
		private var mIterarorDataEnemies:Iterator;
		
		private var mHeartSkin:HeartSkin;
		
		public function EnemyManager(canvas:MovieClip ) {
			mCanvas = canvas;
			mTasks = new List();
			
			mColumns = Global.SW / Global.TILE_WIDTH;
			mRows    = Global.SH / Global.TILE_HEIGHT;
			

			// crear un solo enemigo
			// mTasks.add(new Task(onCreateEnemyChase , 2000));
		}
		/**
		 * Inicialiaro ek juego
		 */
		public function init(heartSkin:HeartSkin):void {
			mHeartSkin = heartSkin;
			// obtener referencia del nivel
			mDataLevel = Global.dataGame.levels[Global.currentLevel];
			mDataEnemies = mDataLevel.cloneEnemies();
			mIterarorDataEnemies = new Iterator(mDataEnemies);
			
			createEnemies();
		}
		
		private function createEnemies():void {
			if (mIterarorDataEnemies.hasNext()) {
				var data_enemy:dtEnemy = mIterarorDataEnemies.next();
				switch (data_enemy.typeAppear) {
					case "TIME":
						mTasks.add(new Task(onCreateEnemyByTime , data_enemy.valueTypeAppear));
						break;
					case "REVIVES":
						if (mHeartSkin.counterEnterBase >= data_enemy.valueTypeAppear) {
							createEnemy(data_enemy);
							// volver a verificar si crear mas enemigos
							mTasks.add(new Task(createEnemies , 100));							
						} else {
							mTasks.add(new Task(onCheckCreateEnemyByRevives , 500));
						}
						break;
				}
			} else {
				// 
				trace("Finish Generate Enemies");
			}
		}
		
		private function onCheckCreateEnemyByRevives():void {
			var data_enemy:dtEnemy = mIterarorDataEnemies.current();
			if (mHeartSkin.counterEnterBase >= data_enemy.valueTypeAppear) {
				createEnemy(data_enemy);
				// volver a verificar si crear mas enemigos
				mTasks.add(new Task(createEnemies , 100));				
			} else {
				mTasks.add(new Task(onCheckCreateEnemyByRevives , 500));
			}	
		}
		
		private function onCreateEnemyByTime():void {
			// verificar si es posible crearlo
			var data_enemy:dtEnemy = mIterarorDataEnemies.current();
			if (data_enemy) {
				if (mList.size() < data_enemy.maxEnemies) {
					createEnemy(data_enemy);
					// volver a crear los enemigos
					mTasks.add(new Task(createEnemies , 100));
				} else {
					// como no cumple volvemos a verificar dentro de 1/2 segundo
					mTasks.add(new Task(onCreateEnemyByTime , 500));
				}
			}
		}
		
		private function createEnemy(data_enemy:dtEnemy):void {
			var enemy:Enemy;
			switch (data_enemy.type) {
				case "HUNTER":
					enemy = new EnemyHunter(mCanvas , "mcEnemyPlayer" , data_enemy.px ,data_enemy.py );			
					break;
				case "FOLLOW":
					enemy = new EnemyFollow(mCanvas , "mcEnemyPlayer" ,data_enemy.px ,data_enemy.py);			
					break;
				case "CHASES":
					enemy = new EnemyChase(mCanvas , "mcEnemyPlayer" ,data_enemy.px ,data_enemy.py);			
					break;
				case "HEART":
					 enemy = new EnemyHeart(mCanvas , "mcEnemyBase" , data_enemy.px ,data_enemy.py);			
					 break;					
			}			
			trace("Generate Enemie " + data_enemy.type);
			mList.add(enemy);
		}
		
		private function generatePosition():Vector2D  {
			var gx:Number;
			var gy:Number;
			
			while (true) {
				gx = helper.randomInterval(150, 600);
				gy = helper.randomInterval(40 , 440);
				
				if (mCanvas.heart_skin) {
					if (!mCanvas.heart_skin.hitTestPoint(gx , gy , true)) {
						break;
					}
				}
			}
			return new Vector2D(gx  , gy);
		}		
		
		private function onCreateEnemyChase():void {
			var column:int = Generic.random( 0 , mColumns -1);
			var row   :int = Generic.random( 0 , mRows    -1);
			
			// crear un enemigo
			/*
			var enemy:EnemyHeart = new EnemyHeart(mCanvas , "mcEnemyBase" ,
					column * Global.TILE_WIDTH +  (Global.TILE_WIDTH * 0.5), row * Global.TILE_HEIGHT + (Global.TILE_HEIGHT * 0.5));
			*/
			// crear un enemigo follower
			var enemyf:EnemyFollow = new EnemyFollow(mCanvas , "mcEnemyPlayer" ,
					column * Global.TILE_WIDTH +  (Global.TILE_WIDTH * 0.5), row * Global.TILE_HEIGHT + (Global.TILE_HEIGHT * 0.5));
			// crear enemigo hunter
			var enemyh:EnemyHunter = new EnemyHunter(mCanvas , "mcEnemyPlayer" ,
					column * Global.TILE_WIDTH +  (Global.TILE_WIDTH * 0.5), row * Global.TILE_HEIGHT + (Global.TILE_HEIGHT * 0.5));
			// crear enemigo base
			var enemyhe:EnemyHeart = new EnemyHeart(mCanvas , "mcEnemyBase" ,
					column * Global.TILE_WIDTH +  (Global.TILE_WIDTH * 0.5), row * Global.TILE_HEIGHT + (Global.TILE_HEIGHT * 0.5));
			
			//mList.add(enemy);
			//mCountEnenmies++;
			mList.add(enemyf);
			mCountEnenmies++;
			mList.add(enemyh);
			mCountEnenmies++;
			mList.add(enemyhe);
			mCountEnenmies++;
			
			if (mCountEnenmies < 3) {
				mTasks.add(new Task(onCreateEnemyChase , 2000));
			}
		}
		
		public function update(dt:int):void {
			if (mTasks) {
				mTasks.update(dt);
			}
			
			if (mList) {
				mList.update(dt);
			}
		}
		
		public function clean():void {	
			if (mList) {
				mList.clean();
				mList = null;
			}			
		}
	}
}